{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type\n",
      "EW      404075\n",
      "E       338648\n",
      "SR      327214\n",
      "VAR     147885\n",
      "SRS     119308\n",
      "EA      101690\n",
      "RRAB     99254\n",
      "ROT      98141\n",
      "EC       94350\n",
      "BY       86947\n",
      "M        82446\n",
      "RS       79597\n",
      "L        40164\n",
      "RRC      39838\n",
      "EB       29270\n",
      "MISC     27295\n",
      "ELL      25730\n",
      "DSCT     15675\n",
      "HADS     10979\n",
      "UG       10482\n",
      "Name: count, dtype: int64 Length 1298\n"
     ]}],
   "source": [
    "\"\"\"Script for plotting a bar chart with types of variable stars in\n",
    "the current version of the AAVSO International Variable Star Index (VSX).\n",
    "Data source: https://cdsarc.cds.unistra.fr/viz-bin/cat/B/vsx\n",
    "\n",
    "According to variable star type designations in vsx,\n",
    "https://www.aavso.org/vsx/index.php?view=about.vartypes\n",
    "A colon (:) after the variability type -or any other field- means\n",
    "the value/classification is uncertain.\n",
    "A pipe character (|) between two different types signifies a logical OR;\n",
    "the classification is uncertain and all possible types are indicated.\n",
    "An example of this is ELL|DSCT, where the star may be an ellipsoidal binary system\n",
    "or a DSCT-type pulsating variable with half the given period.\n",
    "A plus character (+) signifies a logical AND; two different variability types\n",
    "are seen in the same star or system. An example of this would be ELL+DSCT, where\n",
    "one of the components of an ellipsoidal binary system is a DSCT-type pulsating variable.\n",
    "A slash character (/) indicates a subtype. In the case of binary systems (eclipsing,\n",
    "ellipsoidal or reflection variables) it is used to help describe either the physical\n",
    "properties of the system (E/PN or EA/RS), the luminosity class of the components (EA/DM),\n",
    "or the degree of filling of their inner Roche lobes (EA/SD).\n",
    "This is the GCVS classification system. In cataclysmic variables, slash characters\n",
    "are used to indicate some properties of the system, as in the degree of polarization\n",
    "(NA/DQ) or the nature of their components (UG/IBWD).\n",
    "\"\"\"\n",
    "\n",
    "from datetime import datetime\n",
    "import locale\n",
    "import os\n",
    "\n",
    "from scour import scour\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "\n",
    "\n",
    "def optimize_svg(tmp_path, path):\n",
    "    \"\"\"Optimize svg file using scour\"\"\"\n",
    "    with open(tmp_path, \"rb\") as inputfile, open(path, \"wb\") as outputfile:\n",
    "        options = scour.generateDefaultOptions()\n",
    "        options.enable_viewboxing = True\n",
    "        options.strip_comments = True\n",
    "        options.strip_ids = True\n",
    "        options.remove_metadata = True\n",
    "        options.shorten_ids = True\n",
    "        options.indent_type = \"none\"\n",
    "        options.newlines = False\n",
    "        scour.start(options, inputfile, outputfile)\n",
    "\n",
    "\n",
    "data_raw = pd.read_csv(\"../../../data/vsx/vsx_csv.dat\", usecols=[\"Type\"])\n",
    "df = data_raw[\"Type\"].str.strip(\":\")\n",
    "series = df.squeeze()\n",
    "\n",
    "df = series.value_counts()\n",
    "print(df[:20], \"Length\", len(df))"
   ]}, {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "spl +:\n",
      "EP     748\n",
      "ROT    949\n",
      "BY     733\n",
      "UV     885\n",
      "ELL    601\n",
      "dtype: int64\n",
      "spl /:\n",
      "TTS     2017\n",
      "ROT     2375\n",
      "RRAB    1770\n",
      "BL      1878\n",
      "EA      2888\n",
      "dtype: int64\n",
      "spl |:\n",
      "MISC    3881\n",
      "SR      4338\n",
      "EB      3978\n",
      "EW      4867\n",
      "EA      1919\n",
      "dtype: int64\n"
     ]}],
   "source": [
    "df_plus = df[df.index.str.contains(\"+\", regex=False)]\n",
    "df_slash = df[df.index.str.contains(\"/\", regex=False)]\n",
    "df_or = df[df.index.str.contains(\"|\", regex=False)]\n",
    "types_plus = {}\n",
    "types_slash = {}\n",
    "types_or = {}\n",
    "\n",
    "for ind in df_plus.index:\n",
    "    for typsplit in ind.split(\"+\"):\n",
    "        typsplit = typsplit.strip(\":\")\n",
    "        try:\n",
    "            types_plus[typsplit] += df_plus[ind]\n",
    "        except KeyError:\n",
    "            types_plus[typsplit] = df_plus[ind]\n",
    "\n",
    "for ind in df_slash.index:\n",
    "    for typsplit in ind.split(\"/\"):\n",
    "        typsplit = typsplit.strip(\":\")\n",
    "        try:\n",
    "            types_slash[typsplit] += df_slash[ind]\n",
    "        except KeyError:\n",
    "            types_slash[typsplit] = df_slash[ind]\n",
    "\n",
    "for ind in df_or.index:\n",
    "    for typsplit in ind.split(\"|\"):\n",
    "        typsplit = typsplit.strip(\":\")\n",
    "        try:\n",
    "            types_or[typsplit] += df_or[ind]\n",
    "        except KeyError:\n",
    "            types_or[typsplit] = df_or[ind]\n",
    "\n",
    "print(\"spl +:\")\n",
    "print(pd.Series(types_plus)[:5])\n",
    "print(\"spl /:\")\n",
    "print(pd.Series(types_slash)[:5])\n",
    "print(\"spl |:\")\n",
    "print(pd.Series(types_or)[:5])"
   ]}, {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Типы выборки:\n",
      "         vsx    +     /     |\n",
      "EW    404075   12   490  4867\n",
      "E     338648  735   309    17\n",
      "SR    327214  618     0  4338\n",
      "VAR   147885   19     0    12\n",
      "SRS   119308    2     0     0\n",
      "EA    101690  457  2888  1919\n",
      "RRAB   99254    4  1770   103\n",
      "ROT    98141  949  2375    49\n",
      "EC     94350   12     0  3727\n",
      "BY     86947  733    10    25\n",
      "M      82446   25     0    59\n",
      "RS     79597    5   668    26\n",
      "L      40164    3     0   406\n",
      "RRC    39838    1   105   717\n",
      "EB     29270   19   395  3978\n",
      "MISC   27295    0     0  3881\n",
      "ELL    25730  601    43    81\n",
      "DSCT   15675  408     0   982\n",
      "HADS   10979    3     0   133\n",
      "Их количество: 39 всего типов в статистике: 1298 всего звезд в каталоге: 2277355\n"
     ]}, {
     "data": { 
     },
     "metadata": {},
     "output_type": "display_data"
    }],
   "source": [
    "NUM = -39\n",
    "data = pd.DataFrame({\"vsx\": df,\n",
    "                     \"+\": pd.Series(types_plus),\n",
    "                     \"/\": pd.Series(types_slash),\n",
    "                     \"|\": pd.Series(types_or)}).fillna(0).astype(int).sort_values(by=\"vsx\")[NUM:]\n",
    "\n",
    "ax = data.plot.bar(stacked=True, figsize=(16, 9), width=0.88, rot=45)\n",
    "ax.legend([\"Типы переменных звезд VSX\",\n",
    "           \"Звезды с несколькими типами переменности (+)\",\n",
    "           \"Компоненты множественных классификаций затменных (/)\",\n",
    "           \"Возможные типы, неопределенная классификация (|)\"],\n",
    "          fontsize=12, loc=\"upper left\")\n",
    "\n",
    "locale.setlocale(locale.LC_ALL, \"ru_RU\")\n",
    "today = datetime.now()\n",
    "MONTH, YEAR = today.strftime(\"%B\"), today.year\n",
    "\n",
    "print(\"Типы выборки:\")\n",
    "print(data[:-20:-1])\n",
    "print(\"Их количество:\", len(data), \"всего типов в статистике:\",\n",
    "    len(series.value_counts()), \"всего звезд в каталоге:\", len(data_raw))\n",
    "\n",
    "plt.subplots_adjust(left=0.051, bottom=0.102, right=0.985, top=0.955)\n",
    "plt.xlabel(\"Типы переменных звезд\", fontsize=14, labelpad=0)\n",
    "plt.ylabel(\"Количество переменных звезд\", fontsize=14, labelpad=0)\n",
    "plt.title(\"Распределение по типам переменных звезд в текущей версии VSX, \" + \\\n",
    "    f\"всего {len(data_raw)} объектов. Июнь {YEAR} года\", fontsize=15)\n",
    "for x, y in enumerate(data.sum(axis=1)):\n",
    "    ax.annotate(int(y), (x, y+1700), ha=\"center\", fontsize=7)\n",
    "# ax.bar_label(ax.containers[-1], fontsize=7)\n",
    "\n",
    "FILE_EXT = \"png\"\n",
    "PLT_PTH = \"../../../plots/stars/vsx_types_distribution-combined-sorted-latest-spl+\"\n",
    "tmp_pth = f\"{PLT_PTH}_.{FILE_EXT}\"\n",
    "pth = f\"{PLT_PTH}.{FILE_EXT}\"\n",
    "plt.savefig(tmp_pth, dpi=120)\n",
    "if FILE_EXT == \"svg\":\n",
    "    optimize_svg(tmp_pth, pth)\n",
    "    os.remove(tmp_pth)\n"
   ]}],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.3"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
